/**
 * 
 */
package com.vision.core.sv.serv.util;

import java.util.HashSet;
import java.util.Set;

import com.vision.core.cm.db.data.Company;
import com.vision.core.cm.db.data.Permission;
import com.vision.core.cm.db.data.Role;
import com.vision.core.cm.db.data.User;
import com.vision.core.cm.exception.RpcException;
import com.vision.core.sv.security.SessionUtils;
import com.vision.core.sv.util.CollectionUtils;

/**
 * @author Mark
 *
 */
public class ServletUtils {
	
	public static User getLoggedInUser() {
		return SessionUtils.getUser();
	}
	
	public static void checkHasCompany(Company company) throws RpcException {
		if (!getLoggedInUser().getCompanies().contains(company))
			throw new RpcException("The user is not authorized for this company (" + company.getName() + ")!");
	}
	
	public static Set<Permission> getLoggedInUsersPermissions() {
		Set<Role> roles = getLoggedInUser().getRoles();
		Set<Permission> allPermissions = new HashSet<Permission>();
    	for (Role role : roles)
    		allPermissions.addAll(role.getPermissions());
    	return allPermissions;
	}
	
	public static void checkPermissions(String ... requiredPermissions) throws RpcException {
		checkPermissions(false, requiredPermissions);
	}
	
	public static void checkPermissions(boolean matchAll, String ... requiredPermissions) throws RpcException {
		if (requiredPermissions == null || requiredPermissions.length == 0)
			return;
		
		Set<Permission> allPermissions = getLoggedInUsersPermissions();

    	if (matchAll) {
    		boolean hasAll = CollectionUtils.containsAll(allPermissions, "getName", requiredPermissions);
    		if (!hasAll)
    			throw new RpcException("You do not have sufficient permissions to perform this operation.");
    	} else {
    		boolean hasAny = CollectionUtils.containsAny(allPermissions, "getName", requiredPermissions);
    		if (!hasAny)
    			throw new RpcException("You do not have sufficient permissions to perform this operation.");
    	}
	}
	
	public static void checkPermissions(Permission ... requiredPermissions) throws RpcException {
		checkPermissions(false, requiredPermissions);
	}
	
	public static void checkPermissions(boolean matchAll, Permission ... requiredPermissions) throws RpcException {
		if (requiredPermissions == null || requiredPermissions.length == 0)
			return;
		
		Set<Permission> allPermissions = getLoggedInUsersPermissions();
		Set<Permission> required = CollectionUtils.asSet(requiredPermissions);

    	if (matchAll) {
    		boolean hasAll = allPermissions.containsAll(required);
    		if (!hasAll)
    			throw new RpcException("You do not have sufficient permissions to perform this operation.");
    	} else {
    		for (Permission permission : allPermissions) {
    			for (Permission requiredPermission : requiredPermissions) {
    				if (permission.equals(requiredPermission))
    					return;
    			}
    		}
    		
    		throw new RpcException("You do not have sufficient permissions to perform this operation.");
    	}
	}

}
